from baseview import BaseView
from Bases import BaseObject
from ..bases import widgets
from ..editors import EditorBase

class CommSetupView(BaseView):
    topwidget_name = 'Communication Setup'
    topwidget_cls = widgets.Frame
    def __init__(self, **kwargs):
        self.topwidget = widgets.VBox()
        super(CommSetupView, self).__init__(**kwargs)
        self.comm = self.MainController.comm
        
        self.OSCSetup = OSCSetup(MainController=self.MainController)
        self.topwidget.pack_start(self.OSCSetup.topwidget, expand=True)
        self.DMXSetup = DMXSetup(MainController=self.MainController)
        self.topwidget.pack_start(self.DMXSetup.topwidget, expand=True)
        
        self.topwidget.show_all()
        
class OSCSetup(EditorBase):
    topwidget_label = 'OSC Setup'
    def init_editor(self, **kwargs):
        self.osc_io = self.MainController.comm.osc_io
        self.sb_master_priority = widgets.SpinBtn(src_object=self, src_attr='master_priority', 
                                                  allow_obj_setattr=True, label='Master Priority')
        self.topwidget.pack_start(self.sb_master_priority.topwidget)
        c = self.make_child_editor(OSCClient, 'clients')
        self.topwidget.pack_start(c.topwidget, expand=True)
        
    def unlink(self):
        super(OSCSetup, self).unlink()
        self.sb_master_priority.unlink()
        
    @property
    def master_priority(self):
        return self.osc_io.master_priority
    @master_priority.setter
    def master_priority(self, value):
        self.osc_io.master_priority = int(value)
        
class OSCClient(EditorBase):
    topwidget_label = 'Clients'
    def init_editor(self, **kwargs):
        self.osc_io = self.MainController.comm.osc_io
        types = [str, str, int, int, bool, bool, bool, bool]
        self.col_names = ['Name', 'Address', 'Port', 'Priority', 'Master', 'm_active', 'Slave', 's_active']
        self.col_attr_map = {'Name':'name', 'Address':'address', 'Port':'port', 'Priority':'master_priority', 
                             'Master':'isMaster', 'Slave':'isSlave'}
        order = [0, 1, 2, 3, 4, 6]
        self.client_list = widgets.TreeList(name='', list_types=types, column_names=self.col_names, column_order=order)
        self.update_client_list()
        self.topwidget.pack_start(self.client_list.topwidget, expand=True)
        
        self.osc_io.connect('client_added', self.on_client_added)
        self.osc_io.connect('client_removed', self.on_client_removed)
        
    def unlink(self):
        super(OSCClient, self).unlink()
        for cb in [self.on_client_added, self.on_client_removed]:
            self.osc_io.disconnect(callback=cb)
        
    def update_client_list(self, key=None):
        if key:
            clients = {key:self.osc_io.clients[key]}
        else:
            clients = self.osc_io.clients
        for key, val in clients.iteritems():
            if not val.isLocalhost:
                row = []
                for i, name in enumerate(self.col_names):
                    if 'active' in name:
                        value = False
                    else:
                        value = getattr(val, self.col_attr_map[name])
                        if value is None:
                            value = self.client_list.list_types[i]()
                    row.append(value)
                self.client_list.update({key:row[1:]})
        
    def on_client_added(self, **kwargs):
        name = kwargs.get('name')
        self.update_client_list(name)
        
    def on_client_removed(self, **kwargs):
        self.client_list.clear()
        self.update_client_list()
        
class DMXSetup(EditorBase):
    topwidget_label = 'DMX Setup'
    def init_editor(self, **kwargs):
        self.comm = self.MainController.comm
        self.io_editor = None
        
        types = [str, str, bool, bool]
        names = ['id', 'Name', 'Active', 'cell_active']
        order = [1, 2]
        self.io_list = widgets.TreeList(name='', list_types=types, 
                                           column_names=names, column_order=order)
        self.update_io_list()
        self.io_list.connect('selection_changed', self.on_io_list_selection_changed)
        self.io_list.connect('cell_toggled', self.on_io_list_cell_toggled)
        self.topwidget.pack_start(self.io_list.topwidget, expand=True)
        
        self.comm.connect('io_update', self.on_comm_io_update)
        
    def unlink(self):
        super(DMXSetup, self).unlink()
        self.comm.disconnect(callback=self.on_comm_io_update)
        
    def build_io_editor(self, **kwargs):
        obj = kwargs.get('obj')
        if self.io_editor:
            self.io_editor.unlink()
            self.topwidget.remove(self.io_editor.topwidget)
        if obj is not None:
            self.io_editor = self.make_child_editor(DMXIOEditor, 'io_editor', **kwargs)
            self.topwidget.pack_start(self.io_editor.topwidget)
            
    def update_io_list(self, key=None):
        if key:
            cls = self.comm.io_classes[key]
            self.io_list.update({key:[cls.ui_name, key in self.comm.dmx_io, True]})
        else:
            for key, cls in self.comm.io_classes.iteritems():
                self.io_list.update({key:[cls.ui_name, key in self.comm.dmx_io, True]})
                
            
    def on_io_list_selection_changed(self, **kwargs):
        key = kwargs.get('key')
        self.build_io_editor(obj=self.comm.dmx_io.get(key))
        
    def on_io_list_cell_toggled(self, **kwargs):
        key = kwargs.get('key')
        state = kwargs.get('state')
        if state:
            self.comm.build_io(key)
        else:
            self.comm.remove_io(key)
            
    def on_comm_io_update(self, **kwargs):
        key = kwargs.get('key')
        if key not in self.comm.dmx_io:
            key = None
        self.update_io_list(key)
        
class DMXIOEditor(EditorBase):
    topwidget_label = ''
    def init_editor(self, **kwargs):
        self.obj = kwargs.get('obj')
        #self.topwidget = widgets.Frame(label=self.obj.ui_name)
        
        self.btn_connect = widgets.ToggleBtn(label='Connect', src_object=self.obj, src_attr='connected')
        #self.btn_connect.connect('clicked', self.on_btn_connect_clicked)
        self.topwidget.pack_start(self.btn_connect.widget)
        
        self.obj.connect('state_changed', self.btn_connect.on_object_value_changed)
        
    def unlink(self):
        super(DMXIOEditor, self).unlink()
        self.obj.disconnect(callback=self.btn_connect.on_object_value_changed)
    
